using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.ConnectionEngine.Common
{
    /// <summary>
    /// The object representation of a Connection Engine Message.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineMessage
    {
        private ConnectionEngineMessageHeader header;

        /// <summary>
        /// Represents the Header block, where the routing information is stored.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineMessageHeader Header
        {
            get { return header; }
            set { header = value; }
        }
        private ConnectionEngineMessageBody body;

        /// <summary>
        /// Represents the Body block, where the content of the message is stored.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineMessageBody Body
        {
            get { return body; }
            set { body = value; }
        }

        /// <summary>
        /// Creates a new instance of a ConnectionEngineMessage.
        /// </summary>
        public ConnectionEngineMessage()
        {
            this.Header = new ConnectionEngineMessageHeader();
            this.Body = new ConnectionEngineMessageBody();
        }
    }

    /// <summary>
    /// An object representation of a Connection Engine Message Header. This object stores the message's routing information.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineMessageHeader
    {
        private Guid id;

		/// <summary>
		/// Represents the message's unique identifier.
		/// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public Guid ID
        {
            get { return id; }
            set { id = value; }
        }

        private DateTime creationTime;

        /// <summary>
        /// A timestamp represent when the message was created.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public DateTime CreationTime
        {
            get { return creationTime; }
            set { creationTime = value; }
        }
        
        private string sessionToken;

        /// <summary>
        /// Session Token is used to ensure that this message was authenticated before sending. As long as the session token of the message is valid, the message can be processed.
        /// <remarks>This property is not being used by the Connection Engine at this stage, but will be used in the future.</remarks>
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string SessionToken
        {
            get { return sessionToken; }
            set { sessionToken = value; }
        }
        
        private int interactionClass;

        /// <summary>
        /// Identifies interaction class associated with the message's interaction type.
        /// <remarks>This property is not being used by the Connection Engine at this stage, but will be used in the future.</remarks>
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public int InteractionClass
        {
            get { return interactionClass; }
            set { interactionClass = value; }
        }
        
        private int interactionType;

        /// <summary>
        /// Identifies the type of interaction being executed.
        /// <remarks>This property is also referred to as the message type.</remarks>
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public int InteractionType
        {
            get { return interactionType; }
            set { interactionType = value; }
        }
        
        private ConnectionEngineConversation conversation;

        /// <summary>
        /// A unique identifier representing a conversation among Connected Systems.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineConversation Conversation
        {
            get { return conversation; }
            set { conversation = value; }
        }
        
        private ConnectionEngineEndPoint sender;

        /// <summary>
        /// Represents the Connected System sending the message.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineEndPoint Sender
        {
            get { return sender; }
            set { sender = value; }
        }
        
        private ConnectionEngineEndPoint receiver;

        /// <summary>
        /// Represents the Connected System receiving the message.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineEndPoint Receiver
        {
            get { return receiver; }
            set { receiver = value; }
        }
        
        private ConnectionEngineStatus status;

        /// <summary>
        /// Represents the current status of the message.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEngineStatus Status
        {
            get { return status; }
            set { status = value; }
        }

        /// <summary>
        /// Instantiates a new Connection Engine Message Header object.
        /// </summary>
        public ConnectionEngineMessageHeader()
        {
            Initialize();
        }

        /// <summary>
        /// Instantiates a new Connection Engine Message Header object based on the arguments passed as parameters.
        /// </summary>
        /// <param name="senderID">The unique identifier of the Connected System sending the message</param>
        /// <param name="receiverID">The unique identifier of the Connected System receiving the message</param>
        /// <param name="interactionType">The unique identifier the interaction being executed.</param>
        /// <param name="conversationID">The unique identifier of the Conversation thread.</param>
        /// <param name="originalMessageID">The unique identifier of the message this message is replying to.</param>
        public ConnectionEngineMessageHeader(string senderID,
                                                string receiverID,
                                                int interactionType,
                                                Guid conversationID,
                                                Guid originalMessageID)
        {
            Initialize();
            this.Sender.OrganisationID = senderID;
            this.Receiver.OrganisationID = receiverID;
            this.InteractionType = interactionType;
            this.Conversation.ConversationID = conversationID;
            this.Conversation.OriginalMessageID = originalMessageID;
        }

        private void Initialize()
        {
            this.CreationTime = DateTime.Now;
            this.InteractionClass = 0;
            this.InteractionType = 0;
            this.Conversation = new ConnectionEngineConversation();
            this.Sender = new ConnectionEngineEndPoint();
            this.Receiver = new ConnectionEngineEndPoint();
            this.Status = new ConnectionEngineStatus();
        }
    }

    /// <summary>
    /// And object representation of a Connection Engine Conversation Thread.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineConversation
    {
        private Guid conversationID;

        /// <summary>
        /// The unique identifier of the conversation.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public Guid ConversationID
        {
            get { return conversationID; }
            set { conversationID = value; }
        }
        private Guid originalMessageID;

        /// <summary>
        /// The unique identifier of the message this message is replying to. 
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public Guid OriginalMessageID
        {
            get { return originalMessageID; }
            set { originalMessageID = value; }
        }

        /// <summary>
        /// Instantiates a new Connection Engine Conversation object.
        /// </summary>
        public ConnectionEngineConversation()
        {
            this.ConversationID = Guid.Empty;
            this.OriginalMessageID = Guid.Empty;
        }
    }

    /// <summary>
    /// An object representation of a Connected System End Point.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineEndPoint
    {
        private string organisationID;

        /// <summary>
        /// The unique identifier of the Connected System within the Connection Engine.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string OrganisationID
        {
            get { return organisationID; }
            set { organisationID = value; }
        }
        private string connectionEngineUserID;

        /// <summary>
        /// The unique identifier of the Connection Engine user that is sending the message.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string ConnectionEngineUserID
        {
            get { return connectionEngineUserID; }
            set { connectionEngineUserID = value; }
        }
        private string organisationUserID;

        /// <summary>
        /// The unique identifier of the Connected System user that is sending the message.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string OrganisationUserID
        {
            get { return organisationUserID; }
            set { organisationUserID = value; }
        }
        private string uri;

        /// <summary>
        /// The Unique Resource Identifier of the Connected System - this represents the web service URL where the Connected System's Adapter can be located.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string URI
        {
            get { return uri; }
            set { uri = value; }
        }
    }

    /// <summary>
    /// And object representing the Status of a Connection Engine Message. Status can represent success, with a code "0", or error processing a message.
    /// Each error will have a specific code and description.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineStatus
    {
        private int code;

        /// <summary>
        /// The unique identifier of the Status.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public int Code
        {
            get { return code; }
            set { code = value; }
        }
        private string description;

        /// <summary>
        /// A description of the Status' Code.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
        private string details;

        /// <summary>
        /// A place holder to add extra information about the Status (e.g. information about the Exception that triggered the current code).
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string Details
        {
            get { return details; }
            set { details = value; }
        }
    }

    /// <summary>
    /// An object representation of the Connection Engine Message Body. This object stores the message's content information.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEngineMessageBody
    {
        private ConnectionEnginePayload payload;

        /// <summary>
        /// Represents a Connection Engine compatible payload.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public ConnectionEnginePayload Payload
        {
            get { return payload; }
            set { payload = value; }
        }

        /// <summary>
        /// Instantiates a ConnectionEngineMessageBody object.
        /// </summary>
        public ConnectionEngineMessageBody()
        {
            Initialize();
        }

        /// <summary>
        /// Instantiates a ConnectionEngineMessageBody object based on arguments passed as parameters.
        /// </summary>
        /// <param name="encryptionType">The type of encryption used within this payload.</param>
        /// <param name="payloadkey">The encrypted sysmetric key used to decrypt the content.</param>
        /// <param name="payloadiv">The initialization vector used to encrypt the content.</param>
        /// <param name="payloadcontent">The encrypted content.</param>
        public ConnectionEngineMessageBody(Common.CryptoTypes encryptionType, string payloadkey, string payloadiv, string payloadcontent)
        {
            Initialize();
            this.Payload.Content = payloadcontent;
            this.Payload.EncryptionType = encryptionType;
            this.Payload.IV = payloadiv;
            this.Payload.Key = payloadkey;
        }

        /// <summary>
        /// Instantiates a ConnectionEngineMessageBody object based on arguments passed as parameters.
        /// </summary>
        /// <param name="encryptionType">The type of encryption used within this payload.</param>
        /// <param name="encryptedcontent">An object representing the encrypted content.</param>
        public ConnectionEngineMessageBody(Common.CryptoTypes encryptionType, Common.Crypto.EncryptedDataInfo encryptedcontent)
        {
            Initialize();
            this.Payload.Content = encryptedcontent.EncryptedData;
            this.Payload.EncryptionType = encryptionType;
            this.Payload.IV = encryptedcontent.EncryptedIV;
            this.Payload.Key = encryptedcontent.EncryptedKey;
        }

        private void Initialize()
        {
            this.Payload = new ConnectionEnginePayload();
        }
    }

    /// <summary>
    /// And object representation of a Connection Engine compatible payload.
    /// </summary>
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://Microsoft.ConnectionEngine.Messaging")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://Microsoft.ConnectionEngine.Messaging", IsNullable = false)]
    public class ConnectionEnginePayload
    {
        private CryptoTypes encryptionType;

        /// <summary>
        /// Represents the type of encryption used within this payload.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public CryptoTypes EncryptionType
        {
            get { return encryptionType; }
            set { encryptionType = value; }
        }
        private string key;

        /// <summary>
        /// Represents the encrypted key used to decrypt this payload.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string Key
        {
            get { return key; }
            set { key = value; }
        }
        
        private string iv;

        /// <summary>
        /// Represents the initialization vector used when encrypting this payload.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string IV
        {
            get { return iv; }
            set { iv = value; }
        }
        private string content;

        /// <summary>
        /// Represents the encrypted content.
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
        public string Content
        {
            get { return content; }
            set { content = value; }
        }

        /// <summary>
        /// Instantiates a ConnectionEnginePayload object.
        /// </summary>
        public ConnectionEnginePayload()
        {
            this.EncryptionType = CryptoTypes.encTypeNone;
        }
    }

    public enum InteractionClassType
    {
        None = 0,
        List = 1,
        Get = 2,
        Put = 3,
        Route = 4,
        Invoke = 5,
    }

    public enum InteractionTypeType
    {
        None = 0,
        PatientReferral = 1,
        LaboratoryOrderData = 2,
        LaboratoryOrderResult = 3,
        ClinicalDecisionSupportResult = 4,
        PharmacyDispensingStatus = 5,
        DischargeSummary = 6,
        PatientRecordRequest = 7,
        PatientRecordSummary = 8,
        ServiceProviderListRequest = 1000,
        ServiceProviderListResult = 1001,
        HSDReferenceDataRequest = 1002,
        HSDReferenceDataResult = 1003,
        HealthcareUserIdentifierRequest = 1004,
        HealthcareUserIdentifierResult = 1005,
        ServiceProviderDelete = 1006,
        ServiceProviderLock = 1007,
        ServiceProviderUnlock = 1008,
        ServiceProviderUpdate = 1009,
        ServiceProviderInsert = 1010,
        ServiceProviderInsertResult = 1011,
        ServiceProviderUpdateResult = 1012,
        ServiceProviderCheckOutResult = 1013,
        ServiceProviderSearchRequest = 1014,
        ServiceProviderSearchResult = 1015,
        PoolDelete = 1016,
        PoolCheckIn = 1017,
        PoolCheckOut = 1018,
        PoolUpdate = 1019,
        PoolInsert = 1020,
        PoolInsertResult = 1021,
        PoolUpdateResult = 1022,
        PoolCheckOutResult = 1023,
        PoolSearchRequest = 1024,
        PoolSearchResult = 1025,
        ServiceProviderPoolDelete = 1026,
        ServiceProviderPoolInsert = 1027,
        PoolServiceProviderTypeDelete = 1028,
        PoolServiceProviderTypeInsert = 1029,
        ServiceProviderTypeDelete = 1030,
        ServiceProviderTypeCheckIn = 1031,
        ServiceProviderTypeCheckOut = 1032,
        ServiceProviderTypeUpdate = 1033,
        ServiceProviderTypeInsert = 1034,
        ServiceProviderTypeInsertResult = 1035,
        ServiceProviderTypeUpdateResult = 1036,
        ServiceProviderTypeCheckOutResult = 1037,
        PoolCheckInAll = 1038,
        ServiceProviderTypeCheckInAll = 1039,
        ServiceProviderUnlockAll = 1040,
        IRRequest = 1200,
        IRResult = 1201
    }

}
